#!/bin/bash -x
set -x
ProgName=$(basename $0)
BaseDir=$(dirname $(readlink -f "$0"))
LocalAppHome=$(dirname $BaseDir)
SYSOM_UPDATE_LOG=$LOG_HOME/sysom_update.log

####################################################################################################################
# Helper functions
####################################################################################################################

red() {
	printf '\33[1;31m%b\n\33[0m' "$1"
}

green() {
	printf '\33[1;32m%b\n\33[0m' "$1"
}

do_update_microservices() {
	local_microservice_dir=${LocalAppHome}/sysom_server
	if [ ! -d ${local_microservice_dir} ]; then
		local_microservice_dir=${LocalAppHome}/server
	fi
	local_script_dir=$BaseDir/server
	target=$1
	targets=(${target//,/ })
	for target in ${targets[*]}; do
		for service in $(ls ${MICROSERVICE_HOME} | grep ${target}); do
			local_service_dir=${local_microservice_dir}/${service}
			local_service_install_script_dir=${local_script_dir}/${service}
			service_dir=${MICROSERVICE_HOME}/${service}
			service_install_script_dir=${MICROSERVICE_SCRIPT_HOME}/${service}

			if [ -d "${local_service_dir}" ]; then
				rsync -av ${local_service_dir}/ ${service_dir}
			fi

			if [ -d "${local_service_install_script_dir}" ]; then
				rsync -av ${local_service_install_script_dir}/ ${service_install_script_dir}
			fi

			################################################################################################
			# Service conf initial
			################################################################################################
			pushd ${service_dir}
			# update microservice common.py, replace {BASE_DIR.parent.parent}/conf/config.yml to ${SYSOM_CONF}
			if [ -f "${service_dir}/conf/common.py" ]; then
				sed -i "s;{BASE_DIR.parent.parent}/conf/config.yml;/etc/sysom/config.yml;g" ${service_dir}/conf/common.py
			fi
			# update fastapi based microservice alembic/env.py, replace {BASE_DIR.parent.parent}/conf/config.yml to ${SYSOM_CONF}
			if [ -f "${service_dir}/alembic/env.py" ]; then
				sed -i "s;{BASE_DIR.parent.parent}/conf/config.yml;/etc/sysom/config.yml;g" ${service_dir}/alembic/env.py
			fi
			# update microservice gunicorn.py replace /var/log/sysom to ${LOG_HOME}
			if [ -f "${targetservice_dir_dir}/conf/gunicorn.py" ]; then
				sed -i "s;/var/log/sysom;${LOG_HOME};g" ${service_dir}/conf/gunicorn.py
			fi
			popd

			################################################################################################
			# Perform service initial script
			################################################################################################
			if [ ! -f "${service_install_script_dir}/update.sh" ]; then
				continue
			fi

			pushd ${service_install_script_dir}
			green "$service_install_script_dir Updating..................................."
			bash -x ${service_install_script_dir}/update.sh
			if [ $? -ne 0 ]; then
				red "$service_install_script_dir update fail, please check..................................."
				red "sysom update failed, exit 1"
				exit 1
			fi
			popd
		done
	done
}

do_update_environment() {
	mkdir -p ${ENVIRONMENT_HOME}
	local_environment_dir=${LocalAppHome}/environment
	target=$1
	targets=(${target//,/ })
	for target in ${targets[*]}; do
		for env in $(ls ${ENVIRONMENT_HOME} | grep ${target}); do
			target_dir=${ENVIRONMENT_HOME}/${env}
			local_dir=${local_environment_dir}/${env}
			if [ -d "${local_dir}" ]; then
				rsync -av ${local_dir}/ ${target_dir}
			fi

			if [ ! -d "${target_dir}" ] || [ ! -f "${target_dir}/update.sh" ]; then
				continue
			fi

			pushd ${target_dir}

			green "$target_dir Updating..................................."
			bash -x ${target_dir}/update.sh
			if [ $? -ne 0 ]; then
				red "$target_dir update fail, please check..................................."
				red "sysom update failed, exit 1"
				exit 1
			fi

			popd
		done
	done
}

do_update_deps() {
	mkdir -p ${DEPS_HOME}
	local_deps_dir=${LocalAppHome}/deps
	target=$1
	targets=(${target//,/ })
	for target in ${targets[*]}; do
		for dep in $(ls ${DEPS_HOME} | grep ${target}); do
			target_dir=${DEPS_HOME}/${dep}
			local_dir=${local_deps_dir}/${dep}

			if [ -d "${local_dir}" ]; then
				rsync -av ${local_dir}/ ${target_dir}
			fi

			if [ ! -d "${target_dir}" ] || [ ! -f "${target_dir}/update.sh" ]; then
				continue
			fi

			pushd ${target_dir}

			green "$target_dir Updating..................................."
			bash -x ${target_dir}/update.sh
			if [ $? -ne 0 ]; then
				red "$target_dir update fail, please check..................................."
				red "sysom update failed, exit 1"
				exit 1
			fi
			popd
		done
	done
}

####################################################################################################################
# Subcommands
####################################################################################################################

sub_help() {
	echo "Usage: $ProgName <subcommand> [options]"
	echo "Subcommands:"
	echo "    all   Update all modules"
	echo "    env   [ALL | <base_env_name>]        Update all enviroment or specific enviroment"
	echo "          Example: $ProgName env env"
	echo "          Example: $ProgName env sdk"
	echo "    deps  [ALL | <deps_name>]            Update all deps or specific dep"
	echo "          Example: $ProgName dep mysql"
	echo "          Example: $ProgName dep grafana"
	echo "    ms    [ALL | <service_name>]         Update all microservices or specific microservice"
	echo "          Example: $ProgName ms sysom_diagnosis"
	echo ""
	echo "For help with each subcommand run:"
	echo "$ProgName <subcommand> -h|--help"
	echo ""
}

sub_ALL() {
	sub_deps ALL
	sub_env ALL
	sub_ms ALL
	sub_web
}

sub_all() {
	sub_ALL
}

sub_env() {
	sub_environment $@
}

# -> env + sdk
sub_environment() {
	target=$1
	if [ "$target" == "ALL" ]; then
		# Start all enviroment
		for env in $(ls $ENVIRONMENT_HOME); do
			if [ ! -d "${ENVIRONMENT_HOME}/${env}" ]; then
				continue
			fi
			do_update_environment $env
		done
	else
		# Start specific enviroment
		do_update_environment $target
	fi
}

sub_ms() {
	sub_microservice $@
}

sub_server() {
	sub_microservice $@
}

# All microservices
sub_microservice() {
	target=$1
	if [ "$target" == "ALL" ]; then
		# update all microservices
		for microservice in $(ls $MICROSERVICE_HOME); do
			if [ ! -d "${MICROSERVICE_HOME}/${microservice}" ]; then
				continue
			fi
			do_update_microservices ${microservice}
		done
	else
		# update specific microservices
		do_update_microservices $target
	fi
}

sub_deps() {
	target=$1
	if [ "$target" == "ALL" ]; then
		# update all deps
		for dep in $(ls $DEPS_HOME); do
			if [ ! -d "${DEPS_HOME}/${dep}" ]; then
				continue
			fi
			do_update_deps ${dep}
		done
	else
		# update specific deps
		do_update_deps $target
	fi
}

sub_web() {
	local_web_home=${LocalAppHome}/sysom_web
	if [ ! -d ${local_web_home} ]; then
		local_web_home=${LocalAppHome}/web
	fi

	echo ${local_web_home} ${WEB_HOME}

	if [ "${local_web_home}" != "${WEB_HOME}" ]; then
		pushd ${local_web_home}
		if [ -f "index.html" ]; then
			# dist
			rsync -av ${local_web_home}/ ${WEB_HOME}
		else
			# source
			yarn
			yarn build
			rsync -av ${local_web_home}/dist/ ${WEB_HOME}
		fi
		popd
	fi
}

subcommand=$1
case $subcommand in
"" | "-h" | "--help")
	sub_help
	;;
*)
	rpm -q --quiet rsync || yum install -y rsync
	shift
	sub_${subcommand} $@ | tee ${SYSOM_UPDATE_LOG}
	if [ $? = 127 ]; then
		echo "Error: '$subcommand' is not a known subcommand." >&2
		echo "       Run '$ProgName --help' for a list of known subcommands." >&2
		exit 1
	fi
	;;
esac
